# coding=utf-8
import logger as logger
from collections import defaultdict
import json
import os

__author__ = 'Marvin'

scale_values = defaultdict(dict)
file_loaded = False


class MultiHitLogUtils(object):
    def __init__(self):
        pass

    @staticmethod
    def hextorgba(hex_color):
        logger.debug('Starting hextorgba with hex:- ' + hex_color)
        try:
            rgba = [int(hex_color[i:i + 2], 16) for i in range(1, 6, 2)]
            rgba.append(255)
            logger.debug('hextorgba returned :-' + str(tuple(rgba)))
            return tuple(rgba)
        except Exception:
            # todo Better exception handling
            logger.err(Exception.message, 'hex = ' + str(hex_color))
            # print str(hex) + " - Unexpected error:" + str(hex)
            hex_color = '#000000'
            rgba = [int(hex_color[i:i + 2], 16) for i in range(1, 6, 2)]
            rgba.append(255)
            return tuple(rgba)


# todo Evaluate moving to utility class
# noinspection PyPep8
class XvmScale(object):
    def __init__(self, path=None):
        self.scale_file = None
        self.scale_values = defaultdict(dict)
        self.file_loaded = False

        if path is None:
            path = 'configurations/xvmScale.json'
            if os.path.isfile(path):
                self.scale_file = path
                logger.debug('XvmScale: found XvmScale.json, attempting to load', 'file :- ' + self.scale_file)
                self._loadscale(path)
            else:
                logger.debug('XvmScale: initializing without loading XvmScale.json', 'path := ' + path)
        else:
            if 'XvmScale.json' in path:
                if os.path.isfile(path):
                    self.scale_file = path
                    logger.debug('XvmScale: found XvmScale.json, attempting to load', 'file :- ' + self.scale_file)
                    self._loadscale(path)
                else:
                    logger.warn('XvmScale: initializing with supplied argument, file not found!', 'path :- ' + path)
            elif os.path.exists(path):
                if os.path.isfile(os.path.join(path, 'xvmScale.json')):
                    path = os.path.join(path, 'XvmScale.json')
                    logger.debug('XvmScale: found XvmScale.json, attempting to load',
                                 'file :- ' + path)
                    self._loadscale(os.path.join(path, 'XvmScale.json'))
                else:
                    logger.warn('XvmScale: initializing, but XvmScale.json not found at supplied path')
            else:
                logger.warn('XvmScale: initializing but supplied path argument is invalid', 'path :- ' + path)

    def _loadscale(self, file_name=None):
        # todo add checking if file_name is not None:
        """

        :rtype : bool
        """
        if file_name is not None:
            pass

        try:
            j_data = open(self.scale_file)
            self.scale_values = json.load(j_data)
            j_data.close()
            self.file_loaded = True
            logger.debug('xvmscale : loading complete', str(self.scale_values))
            return True
        except Exception:
            # todo Add better exception handling
            logger.err(Exception.message, 'file :- ' + self.scale_file)
            return False

    def is_using_file(self):
        return self.file_loaded

    def convert_to_xwnscale(self, wn8, eff):
        logger.debug('Starting XvmScale conversion', 'wn8:- ' + wn8 + ' eff:- ' + eff + ' file present :- '
                                                     + str(self.file_loaded))
        try:
            if self.file_loaded:
                if wn8 > float(self.scale_values['WN8'][0]):
                    xwn8 = 100
                else:
                    xwn8 = int(max(min(wn8 * (wn8 * (wn8 * (wn8 * (wn8 * (
                        float(self.scale_values['WN8'][1]) * wn8 +
                        float(self.scale_values['WN8'][2])) -
                                                                   float(self.scale_values['WN8'][3])) +
                                                            float(self.scale_values['WN8'][4])) -
                                                     float(self.scale_values['WN8'][5])) +
                                              float(self.scale_values['WN8'][6])) +
                                       float(self.scale_values['WN8'][7]),
                                       100), 0))

                if eff < float(self.scale_values['EFF'][0]):
                    xeff = 0
                else:
                    xeff = int(max(min(eff * ( eff * (eff * (eff * (eff * (
                        float(self.scale_values['EFF'][1]) * eff -
                        float(self.scale_values['EFF'][2])) +
                                                                    float(self.scale_values['EFF'][3])) -
                                                             float(self.scale_values['EFF'][4])) +
                                                      float(self.scale_values['EFF'][5])) -
                                               float(self.scale_values['EFF'][6])) -
                                       float(self.scale_values['EFF'][7]),
                                       100), 0))

            else:
                if wn8 > 3250:
                    xwn8 = 100
                else:
                    xwn8 = int(max(min(wn8 * (wn8 * (wn8 * (wn8 * (wn8 * (
                        0.0000000000000000000812 * wn8 +
                        0.0000000000000001616) -
                                                                   0.000000000006736) +
                                                            0.000000028057) -
                                                     0.00004536) +
                                              0.06563) +
                                       0.01,
                                       100), 0))

                if eff < 350:
                    xeff = 0
                else:
                    xeff = int(max(min(eff * ( eff * (eff * (eff * (eff * (
                        0.00000000000000003388 * eff -
                        0.0000000000002469) +
                                                                    0.00000000069335) -
                                                             0.00000095342) +
                                                      0.0006656) -
                                               0.1485) -
                                       0.85,
                                       100), 0))
            logger.debug('xvmscale : returning xwn8 :- ' + str(xwn8) + ' xeff:- ' + str(xeff))
            return xwn8, xeff
        except ValueError as v_error:
            # todo Add better exception handling
            logger.err(v_error.message, 'wn8 := ' + str(wn8) + ' eff := ' + str(eff))
            return 0, 0
        except OverflowError as o_error:
            logger.err(o_error.message, 'wn8 := ' + str(wn8) + ' eff := ' + str(eff))
            return 0, 0
